﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace Pavilion.NodeDesigner
{
    public struct ConnectorInfo
    {
        public double DesignerItemLeft { get; set; }
        public double DesignerItemTop { get; set; }
        public Size DesignerItemSize { get; set; }
        public Point Position { get; set; }
        public ConnectorOrientation Orientation { get; set; }
    }

    public enum ConnectorOrientation
    {
        None,
        Left,
        Top,
        Right,
        Bottom
    }

    public class Anchor : Control
    {
        private static readonly Point DEFAULT_pointOnCanvas = new Point(0, 0);

        public ConnectorOrientation Orientation { get; set; }

        public double XonCanvas
        {
            get { return CalculateXPositionOnCanvas(); }
        }

        public double YonCanvas
        {
            get { return CalculateYPositionOnCanvas(); }
        }

        public Anchor()
        {
            DefaultStyleKey = typeof(Anchor);
            base.Loaded += (x, y) =>
                {
                    var parent = NewWayHelper.GetParentWhoseAncestorIsType(this, typeof(Canvas)) as ContentControl;
                    if (parent != null)
                        parent.GiveFeedback += (sender, args) => MessageBox.Show("Yay!");
                };
        }

        public event Action<Point> PositionChanged;
        private void OnPositionChanged(Point newPosition)
        {
            if (PositionChanged != null)
                PositionChanged(newPosition);
        }

            
        public ConnectorInfo GetInfo()
        {
            var parentOnCanvas = NewWayHelper.GetParentWhoseAncestorIsType(this, typeof(Canvas)) as FrameworkElement;

            ConnectorInfo info = new ConnectorInfo();
            info.DesignerItemLeft = Canvas.GetLeft(parentOnCanvas);
            info.DesignerItemTop = Canvas.GetTop(parentOnCanvas);
            info.DesignerItemSize = new Size(parentOnCanvas.ActualWidth, parentOnCanvas.ActualHeight);
            info.Orientation = this.Orientation;
            info.Position = new Point(XonCanvas, YonCanvas);

            return info;
        }        

        private Point UpdateConnectorPosition()
        {
            Canvas parentCanvas = NewWayHelper.GetAncestor(this, typeof(Canvas)) as Canvas;
            if (parentCanvas != null)
                return TransformToAncestor(parentCanvas).Transform(new Point(this.Width / 2, this.Height / 2)); 
            else
                return DEFAULT_pointOnCanvas;
        }

        private double CalculateXPositionOnCanvas()
        {
            double xPosition;
            
            var parentOnCanvas = NewWayHelper.GetParentWhoseAncestorIsType(this, typeof(Canvas)) as FrameworkElement;
            if (this.Orientation == ConnectorOrientation.Bottom || this.Orientation == ConnectorOrientation.Top)
                xPosition = Canvas.GetLeft(parentOnCanvas) + parentOnCanvas.ActualWidth / 2;
            else if (this.Orientation == ConnectorOrientation.Left)
                xPosition = Canvas.GetLeft(parentOnCanvas);
            else if (this.Orientation == ConnectorOrientation.Right)
                xPosition = Canvas.GetLeft(parentOnCanvas) + parentOnCanvas.ActualWidth;
            else
                throw new Exception("Invalid anchor orientation");

            return xPosition;
        }

        private double CalculateYPositionOnCanvas()
        {
            double yPosition;
            var parentOnCanvas = NewWayHelper.GetParentWhoseAncestorIsType(this, typeof(Canvas)) as FrameworkElement;
            if (this.Orientation == ConnectorOrientation.Right || this.Orientation == ConnectorOrientation.Left)
                yPosition = Canvas.GetTop(parentOnCanvas) + parentOnCanvas.ActualHeight / 2;
            else if (this.Orientation == ConnectorOrientation.Bottom)
                yPosition = Canvas.GetTop(parentOnCanvas) + parentOnCanvas.ActualHeight;
            else if (this.Orientation == ConnectorOrientation.Top)
                yPosition = Canvas.GetTop(parentOnCanvas);
            else
                throw new Exception("Invalid anchor orientation");

            return yPosition;
        }


        public void UpdatePosition()
        {
            OnPositionChanged(new Point(XonCanvas,YonCanvas));
        }
    }
}
